//
// Copyright (c) 2009 All Right Reserved
//
// Stephen Toub
// stoub@microsoft.com
// 2009-01-01
// Contains ...
namespace LargoCommon.Midi
{
using Abstract;
using JetBrains.Annotations;
using Music;
using System;
using System.Globalization;
using System.IO;
using System.Text;
/// MIDI event to modify the pitch of all notes played on the channel.
[Serializable]
public sealed class VoicePitchWheel : VoiceEvent {
#region Fields
/// The category status byte for PitchWheel messages.
private const byte CategoryStatusByte = 0xE;
/// The upper 7-bits of the wheel position..
private byte upperBits;
/// The lower 7-bits of the wheel position..
private byte lowerBits;
#endregion
#region Constructors
/// Initializes a new instance of the VoicePitchWheel class.
/// The delta-time since the previous message.
/// The channel to which to write the message (0 through 15).
/// The upper 7 bits of the position.
/// The lower 7 bits of the position.
public VoicePitchWheel(long deltaTime, MidiChannel channel, byte upperBits, byte lowerBits) :
base(deltaTime, CategoryStatusByte, channel) {
this.UpperBits = upperBits;
this.LowerBits = lowerBits;
}
/// Initializes a new instance of the VoicePitchWheel class.
/// The amount of time before this event.
/// The category identifier (0x0 through 0xF) for this voice event.
/// The channel (0x0 through 0xF) for this voice event.
public VoicePitchWheel(long deltaTime, byte givenCategory, MidiChannel channel)
: base(deltaTime, givenCategory, channel) {
}
#endregion
#region Properties
/// Gets The first parameter as sent in the MIDI message.
/// General musical property.
public override byte Parameter1 => (byte)((this.Position & DefaultValue.MaskFirstByte) >> 8);
/// Gets The second parameter as sent in the MIDI message.
/// General musical property.
public override byte Parameter2 => (byte)(this.Position & 0xFF);
/// Gets or sets the upper 7 bits of the position.
/// General musical property.
private byte UpperBits {
get => this.upperBits;
set {
if (this.upperBits > 0x7F) {
throw new ArgumentOutOfRangeException(nameof(value), value, "Value must be in the range from 0x0 to 0x7F.");
}
this.upperBits = value;
}
}
/// Gets or sets the lower 7 bits of the position.
/// General musical property.
private byte LowerBits {
get => this.lowerBits;
set {
if (this.lowerBits > 0x7F) {
throw new ArgumentOutOfRangeException(nameof(value), value, "Value must be in the range from 0x0 to 0x7F.");
}
this.lowerBits = value;
}
}
/// Gets or sets the wheel position.
/// General musical property.
private int Position {
get => MidiEvent.CombineBytesTo14Bits(this.upperBits, this.lowerBits);
[UsedImplicitly]
set {
if (value < 0 || value > 0x3FFF) {
throw new ArgumentOutOfRangeException(nameof(value), value, "Pitch wheel position must be in the range from 0x0 to 0x3FFF.");
}
MidiEvent.Split14BitsToBytes(value, out this.upperBits, out this.lowerBits);
}
}
#endregion
#region To String
/// Generate a string representation of the event.
/// A string representation of the event.
public override string ToString() {
var sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append("\t");
sb.Append(this.Position.ToString(CultureInfo.CurrentCulture.NumberFormat));
sb.Append(" (");
sb.Append(this.LowerBits.ToString(CultureInfo.CurrentCulture.NumberFormat));
sb.Append(",");
sb.Append(this.UpperBits.ToString(CultureInfo.CurrentCulture.NumberFormat));
sb.Append(")");
return sb.ToString();
}
#endregion
#region Methods
/// Write the event to the output stream.
/// The stream to which the event should be written.
public override void Write(Stream outputStream) {
if (outputStream == null) {
return;
}
//// Write out the base event information
base.Write(outputStream);
// Write out the data
//// int position = this.Position;
outputStream.WriteByte(this.Parameter1);
outputStream.WriteByte(this.Parameter2);
}
#endregion
}
}